package com.example.ticket.demo;

import com.example.ticket.demo.model.table.Ticket;
import com.example.ticket.demo.service.ITicketService;
import com.example.ticket.demo.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 售票
 *
 * @author liu.nh
 */
@Slf4j
public class TicketSaleManager {

    private static ITicketService ticketService;
    //要确保tickCount只有一个实例
    public static volatile int tickCount;
    //要确保ticketLock只有一个实例
    public static volatile Lock ticketLock;

    public TicketSaleManager() {
        if (ticketService == null){
            ticketService = SpringUtils.getBean("ticketService");
        }
        if (ticketLock == null){
            ticketLock = new ReentrantLock();
        }
    }

    public void saleTicket(String salerName, int saleCount) {
        log.info("========================================================");
        synchronized (TicketSaleManager.class) {
            Ticket ticket = ticketService.selectByType("movie");
            tickCount = ticket.getTicketCount();
            try {
                if (tickCount > 0) {
                    if (saleCount > tickCount) {
                        saleCount = tickCount;
                    }
                    log.info(salerName + ": 售出" + saleCount + "张票。");
                    tickCount = tickCount - saleCount;

                    Ticket record = new Ticket();
                    record.setId(ticket.getId());
                    record.setTicketCount(tickCount);
                    record.setType("movie");
                    ticketService.updateTicketSale(record);
                    log.info(">>>剩下" + tickCount + "张票。");
                } else {
                    log.info(">>>票已被售完。");
                }
            } catch (Exception e) {
                log.error("sale Exception", e);
            }
        }
    }

    public void saleTicket1(String salerName, int saleCount) {
        log.info("========================================================");
        try {
            ticketLock.lock();
            Ticket ticket = ticketService.selectByType("movie");
            tickCount = ticket.getTicketCount();
            if (tickCount > 0) {
                if (saleCount > tickCount) {
                    saleCount = tickCount;
                }
                log.info(salerName + ": 售出" + saleCount + "张票。");
                tickCount = tickCount - saleCount;

                Ticket record = new Ticket();
                record.setId(ticket.getId());
                record.setTicketCount(tickCount);
                record.setType("movie");
                ticketService.updateTicketSale(record);
                log.info(">>>剩下" + tickCount + "张票。");
            } else {
                log.info(">>>票已被售完。");
            }
        } catch (Exception e) {
            log.error("sale1 Exception", e);
        } finally {
            try {
                ticketLock.unlock();
            } catch (Exception e) {
                log.error("sale1 unlock Exception", e);
            }
        }
    }


    /**
     * 会出现线程安全问题
     * @param salerName
     * @param saleCount
     */
    public void saleTicket2(String salerName, int saleCount) {
        log.info("========================================================");
        try {
            Ticket ticket = ticketService.selectByType("movie");
            tickCount = ticket.getTicketCount();
            if (tickCount > 0) {
                if (saleCount > tickCount) {
                    saleCount = tickCount;
                }
                log.info(salerName + ": 售出" + saleCount + "张票。");
                tickCount = tickCount - saleCount;

                Ticket record = new Ticket();
                record.setId(ticket.getId());
                record.setTicketCount(tickCount);
                record.setType("movie");
                int resultInt = ticketService.updateTicketSale(record);
                log.info(">>>剩下" + tickCount + "张票。");
            } else {
                log.info(">>>票已被售完。");
            }
        } catch (Exception e) {
            log.error("sale3 Exception", e);
        }
    }
}
